@@ -2353,17 +2353,12 @@ static bool needsPtLoad(OutputSection *sec) {
2353
2353
return true ;
2354
2354
}
2355
2355
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.
2360
2357
static uint64_t computeFlags (uint64_t flags) {
2361
2358
if (config->omagic )
2362
2359
return PF_R | PF_W | PF_X;
2363
2360
if (config->executeOnly && (flags & PF_X))
2364
2361
return flags & ~PF_R;
2365
- if (config->singleRoRx && !(flags & PF_W))
2366
- return flags | PF_X;
2367
2362
return flags;
2368
2363
}
2369
2364
@@ -2451,7 +2446,7 @@ SmallVector<PhdrEntry *, 0> Writer<ELFT>::createPhdrs(Partition &part) {
2451
2446
// Segments are contiguous memory regions that has the same attributes
2452
2447
// (e.g. executable or writable). There is one phdr for each segment.
2453
2448
// 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
2455
2450
// using AT or AT> linker script command, respectively.
2456
2451
//
2457
2452
// 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) {
2465
2460
// so when hasSectionsCommand, since we cannot introduce the extra alignment
2466
2461
// needed to create a new LOAD)
2467
2462
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
+
2468
2470
bool sameLMARegion =
2469
2471
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 {
2475
2479
load = addHdr (PT_LOAD, newFlags);
2476
2480
flags = newFlags;
2477
2481
}
0 commit comments