@@ -2353,17 +2353,12 @@ static bool needsPtLoad(OutputSection *sec) {
23532353 return true ;
23542354}
23552355
2356- // Linker scripts are responsible for aligning addresses. Unfortunately, most
2357- // linker scripts are designed for creating two PT_LOADs only, one RX and one
2358- // RW. This means that there is no alignment in the RO to RX transition and we
2359- // cannot create a PT_LOAD there.
2356+ // Adjust phdr flags according to certain options.
23602357static uint64_t computeFlags (uint64_t flags) {
23612358 if (config->omagic )
23622359 return PF_R | PF_W | PF_X;
23632360 if (config->executeOnly && (flags & PF_X))
23642361 return flags & ~PF_R;
2365- if (config->singleRoRx && !(flags & PF_W))
2366- return flags | PF_X;
23672362 return flags;
23682363}
23692364
@@ -2451,7 +2446,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
24512446 // Segments are contiguous memory regions that has the same attributes
24522447 // (e.g. executable or writable). There is one phdr for each segment.
24532448 // Therefore, we need to create a new phdr when the next section has
2454- // different flags or is loaded at a discontiguous address or memory region
2449+ // compatible flags or is loaded at a discontiguous address or memory region
24552450 // using AT or AT> linker script command, respectively.
24562451 //
24572452 // As an exception, we don't create a separate load segment for the ELF
@@ -2465,13 +2460,22 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
24652460 // so when hasSectionsCommand, since we cannot introduce the extra alignment
24662461 // needed to create a new LOAD)
24672462 uint64_t newFlags = computeFlags (sec->getPhdrFlags ());
2463+ // When --no-rosegment is specified, RO and RX sections are compatible.
2464+ uint32_t diff = flags ^ newFlags;
2465+ if (config->singleRoRx && !(newFlags & PF_W))
2466+ diff &= ~PF_X;
2467+ if (diff)
2468+ load = nullptr ;
2469+
24682470 bool sameLMARegion =
24692471 load && !sec->lmaExpr && sec->lmaRegion == load->firstSec ->lmaRegion ;
2470- if (!(load && newFlags == flags && sec != relroEnd &&
2471- sec->memRegion == load->firstSec ->memRegion &&
2472- (sameLMARegion || load->lastSec == Out::programHeaders) &&
2473- (script->hasSectionsCommand || sec->type == SHT_NOBITS ||
2474- load->lastSec ->type != SHT_NOBITS))) {
2472+ if (load && sec != relroEnd &&
2473+ sec->memRegion == load->firstSec ->memRegion &&
2474+ (sameLMARegion || load->lastSec == Out::programHeaders) &&
2475+ (script->hasSectionsCommand || sec->type == SHT_NOBITS ||
2476+ load->lastSec ->type != SHT_NOBITS)) {
2477+ load->p_flags |= newFlags;
2478+ } else {
24752479 load = addHdr (PT_LOAD, newFlags);
24762480 flags = newFlags;
24772481 }
0 commit comments