facebookarchive / BOLT

Binary Optimization and Layout Tool - A linux command-line utility used for optimizing performance of binaries
2.52k stars 178 forks source link

Is it possible to resize a section from a BinaryFunctionPass? #285

Closed scottconstable closed 2 years ago

scottconstable commented 2 years ago

I am trying to figure out how to expand the .rodata section from by BinaryFunctionPass. I can get the section and confirm that its size matches what I see in objdump, but then when I try to addPatch some bytes I do not observe any change in the output binary. Looking through the BOLT source code, I see some examples in RewriteInstance.cpp that appear to patch some data sections, but it isn't clear to me how these patches materialize in the final binary. Is there a convenient way to resize a data section from a BinaryFunctionPass?

Here is my experimental code:

void ExperimentalPass::runOnFunctions(BinaryContext &BC) {
  auto MaybeRodata = BC.getUniqueSectionByName(".rodata");
  auto RodataError = MaybeRodata.getError();
  if (RodataError) {
    errs() << RodataError.message() << '\n';
    exit(1);
  }
  BinarySection &Rodata = MaybeRodata.get();
  uint64_t RodataSize = Rodata.getSize();
  SmallVector<char> Bytes = {1, 2, 3, 4};
  Rodata.addPatch(RodataSize, Bytes);
  ...
}
maksfb commented 2 years ago

Resizing an existing allocatable section in-place is not currently possible. You can allocate a new section, e.g. .rodata and place new contents in there. This new section will be allocated in a newly created segment. The old section will be renamed .bolt.org.rodata. E.g., this is something BOLT does under -jump-tables=move option where new jump tables are being placed in .rodata.

scottconstable commented 2 years ago

Hi, thanks for the prompt response. I now see that I can effectively create a new rodata section with the BinaryContext::registerOrUpdateSection API. Thanks!