c++portable-executablecoffbfd

libbfd: Write COFF object with AMD64 machine type


Im using libbfd to write out the contents of a coff object file for windows that contains x86-64 code. Writing symbols, sections and relocations works, but the resulting file does not have the machine type set in the coff header. I manually write 0x8664 at the beginning of the file to fix this issue.

Is there a way to use the bfd API to set the machine type of the object?

This is my code to write the object file:

bfd_init();
auto bfd = bfd_openw("test.obj", "pe-x86-64");
if (!bfd) {
    bfd_perror("bfd_openw failed");
    return -1;
}
if (!bfd_set_format(bfd, bfd_object)) {
    bfd_perror("bfd_set_format failed");
    return -1;
}

// now write some sections, symbols and relocations

bfd_close(bfd);

// TODO hack: overwrite first two bytes of file to make it a AMD64 coff file
std::fstream obj_file("test.obj", std::ios::binary | std::ios::in | std::ios::out);
obj_file.seekp(0, std::ios::beg);
obj_file.write("\x64\x86", 2);

Solution

  • The answer is quite simple, but cannot be found that easily in the documentation... when opening the bfd object, bfd_set_arch_info must be used to set the architecture.

    bfd_init();
    auto bfd = bfd_openw("test.obj", "pe-x86-64");
    if (!bfd) {
        bfd_perror("bfd_openw failed");
        return -1;
    }
    if (!bfd_set_format(bfd, bfd_object)) {
        bfd_perror("bfd_set_format failed");
        return -1;
    }
    // now set the architecture:
    bfd_set_arch_info(bfd, bfd_lookup_arch(bfd_arch_i386, bfd_mach_x86_64));