1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * Map file parsing and input section to output segment mapping. 33 */ 34 #include <stdio.h> 35 #include <string.h> 36 #include <debug.h> 37 #include "msg.h" 38 #include "_libld.h" 39 40 /* 41 * Each time a section is placed, the function set_addralign() 42 * is called. This function performs: 43 * 44 * . if the section is from an external file, check if this is empty or not. 45 * If not, we know the segment this section will belong needs a program 46 * header. (Of course, the program is needed only if this section falls 47 * into a loadable segment.) 48 * . compute the Least Common Multiplier for setting the segment alignment. 49 */ 50 static void 51 set_addralign(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp) 52 { 53 Shdr * shdr = isp->is_shdr; 54 55 /* A discarded section has no influence on the output */ 56 if (isp->is_flags & FLG_IS_DISCARD) 57 return; 58 59 /* 60 * If this section has data or will be assigned data 61 * later, mark this segment not-empty. 62 */ 63 if ((shdr->sh_size != 0) || 64 ((isp->is_flags & FLG_IS_EXTERNAL) == 0)) 65 osp->os_sgdesc->sg_flags |= FLG_SG_PHREQ; 66 67 if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) && 68 (osp->os_sgdesc->sg_phdr).p_type != PT_LOAD) 69 return; 70 71 osp->os_sgdesc->sg_addralign = 72 ld_lcm(osp->os_sgdesc->sg_addralign, shdr->sh_addralign); 73 } 74 75 /* 76 * Place a section into the appropriate segment. 77 */ 78 Os_desc * 79 ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link) 80 { 81 Listnode * lnp1, * lnp2; 82 Ent_desc * enp; 83 Sg_desc * sgp; 84 Os_desc **ospp, *osp; 85 Aliste off1, off2; 86 int os_ndx; 87 Shdr * shdr = isp->is_shdr; 88 Xword shflagmask, shflags = shdr->sh_flags; 89 Ifl_desc * ifl = isp->is_file; 90 91 /* 92 * Define any sections that must be thought of as referenced. These 93 * sections may not be referenced externaly in a manner ld(1) can 94 * discover, but they must be retained (ie. not removed by -zignore). 95 */ 96 static const Msg RefSecs[] = { 97 MSG_SCN_INIT, /* MSG_ORIG(MSG_SCN_INIT) */ 98 MSG_SCN_FINI, /* MSG_ORIG(MSG_SCN_FINI) */ 99 MSG_SCN_EX_RANGES, /* MSG_ORIG(MSG_SCN_EX_RANGES) */ 100 MSG_SCN_EX_SHARED, /* MSG_ORIG(MSG_SCN_EX_SHARED) */ 101 MSG_SCN_CTORS, /* MSG_ORIG(MSG_SCN_CTORS) */ 102 MSG_SCN_DTORS, /* MSG_ORIG(MSG_SCN_DTORS) */ 103 MSG_SCN_EHFRAME, /* MSG_ORIG(MSG_SCN_EHFRAME) */ 104 MSG_SCN_EHFRAME_HDR, /* MSG_ORIG(MSG_SCN_EHFRAME_HDR) */ 105 MSG_SCN_JCR, /* MSG_ORIG(MSG_SCN_JCR) */ 106 0 107 }; 108 109 DBG_CALL(Dbg_sec_in(ofl->ofl_lml, isp)); 110 111 if ((shflags & SHF_GROUP) || (shdr->sh_type == SHT_GROUP)) { 112 Group_desc * gdesc; 113 114 if ((gdesc = ld_get_group(ofl, isp)) == (Group_desc *)S_ERROR) 115 return ((Os_desc *)S_ERROR); 116 117 if (gdesc) { 118 DBG_CALL(Dbg_sec_group(ofl->ofl_lml, isp, gdesc)); 119 120 /* 121 * If this group is marked as discarded, then this 122 * section needs to be discarded. 123 */ 124 if (gdesc->gd_flags & GRP_FLG_DISCARD) { 125 isp->is_flags |= FLG_IS_DISCARD; 126 /* 127 * Since we're discarding the section, we 128 * can skip assigning it to an output section. 129 * The exception is that if the user 130 * specifies -z relaxreloc, then 131 * we need to assign the output section so 132 * that the sloppy relocation logic will have 133 * the information necessary to do its work. 134 */ 135 if (!(ofl->ofl_flags1 & FLG_OF1_RLXREL)) 136 return ((Os_desc *)0); 137 } 138 } 139 140 /* 141 * SHT_GROUP sections can only be included into relocatable 142 * objects. 143 */ 144 if (shdr->sh_type == SHT_GROUP) { 145 if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) { 146 isp->is_flags |= FLG_IS_DISCARD; 147 return ((Os_desc *)0); 148 } 149 } 150 } 151 152 /* 153 * Always assign SHF_TLS sections to the DATA segment (and then the 154 * PT_TLS embedded inside of there). 155 */ 156 if (shflags & SHF_TLS) 157 shflags |= SHF_WRITE; 158 159 /* 160 * Traverse the entrance criteria list searching for a segment that 161 * matches the input section we have. If an entrance criterion is set 162 * then there must be an exact match. If we complete the loop without 163 * finding a segment, then sgp will be NULL. 164 */ 165 sgp = NULL; 166 for (LIST_TRAVERSE(&ofl->ofl_ents, lnp1, enp)) { 167 if (enp->ec_segment && 168 (enp->ec_segment->sg_flags & FLG_SG_DISABLED)) 169 continue; 170 if (enp->ec_type && (enp->ec_type != shdr->sh_type)) 171 continue; 172 if (enp->ec_attrmask && 173 /* LINTED */ 174 (enp->ec_attrmask & enp->ec_attrbits) != 175 (enp->ec_attrmask & shflags)) 176 continue; 177 if (enp->ec_name && (strcmp(enp->ec_name, isp->is_name) != 0)) 178 continue; 179 if (enp->ec_files.head) { 180 char *file; 181 int found = 0; 182 183 if (isp->is_file == 0) 184 continue; 185 186 for (LIST_TRAVERSE(&(enp->ec_files), lnp2, file)) { 187 const char *name = isp->is_file->ifl_name; 188 189 if (file[0] == '*') { 190 const char *basename; 191 192 basename = strrchr(name, '/'); 193 if (basename == NULL) 194 basename = name; 195 else if (basename[1] != '\0') 196 basename++; 197 198 if (strcmp(&file[1], basename) == 0) { 199 found++; 200 break; 201 } 202 } else { 203 if (strcmp(file, name) == 0) { 204 found++; 205 break; 206 } 207 } 208 } 209 if (!found) 210 continue; 211 } 212 break; 213 } 214 215 if ((sgp = enp->ec_segment) == 0) 216 sgp = ((Ent_desc *)(ofl->ofl_ents.tail->data))->ec_segment; 217 218 isp->is_basename = isp->is_name; 219 220 /* 221 * Strip out the % from the section name in all cases except when '-r' 222 * is used without '-M', and '-r' is used with '-M' without 223 * the ?O flag. 224 */ 225 if (((ofl->ofl_flags & FLG_OF_RELOBJ) && 226 (sgp->sg_flags & FLG_SG_ORDER)) || 227 !(ofl->ofl_flags & FLG_OF_RELOBJ)) { 228 char *cp; 229 230 if ((cp = strchr(isp->is_name, '%')) != NULL) { 231 char *name; 232 size_t size = (size_t)(cp - isp->is_name); 233 234 if ((name = libld_malloc(size + 1)) == 0) 235 return ((Os_desc *)S_ERROR); 236 (void) strncpy(name, isp->is_name, size); 237 cp = name + size; 238 *cp = '\0'; 239 isp->is_name = name; 240 } 241 isp->is_txtndx = enp->ec_ndx; 242 } 243 244 /* 245 * Assign a hash value now that the section name has been finalized. 246 */ 247 isp->is_namehash = sgs_str_hash(isp->is_name); 248 249 if (sgp->sg_flags & FLG_SG_ORDER) 250 enp->ec_flags |= FLG_EC_USED; 251 252 /* 253 * If the link is not 0, then the input section is going to be appended 254 * to the output section. The append occurs at the input section 255 * pointed to by the link. 256 */ 257 if (link != 0) { 258 osp = isp->is_file->ifl_isdesc[link]->is_osdesc; 259 260 /* 261 * If this is a COMDAT section, then see if this 262 * section is a keeper and/or if it is to be discarded. 263 */ 264 if (shdr->sh_type == SHT_SUNW_COMDAT) { 265 Listnode * clist; 266 Is_desc * cisp; 267 268 for (LIST_TRAVERSE(&(osp->os_comdats), clist, cisp)) { 269 if (strcmp(isp->is_basename, cisp->is_basename)) 270 continue; 271 272 isp->is_flags |= FLG_IS_DISCARD; 273 isp->is_osdesc = osp; 274 DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml, 275 isp, cisp)); 276 return (0); 277 } 278 279 /* 280 * This is a new COMDAT section - so keep it. 281 */ 282 if (list_appendc(&(osp->os_comdats), isp) == 0) 283 return ((Os_desc *)S_ERROR); 284 } 285 286 /* 287 * Set alignment 288 */ 289 set_addralign(ofl, osp, isp); 290 291 if (list_appendc(&(osp->os_isdescs), isp) == 0) 292 return ((Os_desc *)S_ERROR); 293 294 isp->is_osdesc = osp; 295 sgp = osp->os_sgdesc; 296 297 DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp)); 298 return (osp); 299 } 300 301 /* 302 * Determine if section ordering is turned on. If so, return the 303 * appropriate os_txtndx. This information is derived from the 304 * Sg_desc->sg_segorder list that was built up from the Mapfile. 305 */ 306 os_ndx = 0; 307 if (sgp->sg_secorder) { 308 Aliste off; 309 Sec_order **scopp; 310 311 for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) { 312 Sec_order *scop = *scopp; 313 314 if (strcmp(scop->sco_secname, isp->is_name) == 0) { 315 scop->sco_flags |= FLG_SGO_USED; 316 os_ndx = scop->sco_index; 317 break; 318 } 319 } 320 } 321 322 /* 323 * Mask of section header flags to ignore when 324 * matching sections. We are more strict with 325 * relocatable objects, ignoring only the order 326 * flags, and keeping sections apart if they differ 327 * otherwise. This follows the policy that sections 328 * in a relative object should only be merged if their 329 * flags are the same, and avoids destroying information 330 * prematurely. For final products however, we ignore all 331 * flags that do not prevent a merge. 332 */ 333 shflagmask = (ofl->ofl_flags & FLG_OF_RELOBJ) 334 ? ALL_SHF_ORDER : ALL_SHF_IGNORE; 335 336 /* 337 * Traverse the input section list for the output section we have been 338 * assigned. If we find a matching section simply add this new section. 339 */ 340 off2 = 0; 341 for (ALIST_TRAVERSE(sgp->sg_osdescs, off1, ospp)) { 342 Shdr *_shdr; 343 344 osp = *ospp; 345 _shdr = osp->os_shdr; 346 347 if ((ident == osp->os_scnsymndx) && (ident != M_ID_REL) && 348 (isp->is_namehash == osp->os_namehash) && 349 (shdr->sh_type != SHT_GROUP) && 350 (shdr->sh_type != SHT_SUNW_dof) && 351 ((shdr->sh_type == _shdr->sh_type) || 352 ((shdr->sh_type == SHT_SUNW_COMDAT) && 353 (_shdr->sh_type == SHT_PROGBITS))) && 354 ((shflags & ~shflagmask) == 355 (_shdr->sh_flags & ~shflagmask)) && 356 (strcmp(isp->is_name, osp->os_name) == 0)) { 357 /* 358 * If this is a COMDAT section, determine if this 359 * section is a keeper, and/or if it is to be discarded. 360 */ 361 if (shdr->sh_type == SHT_SUNW_COMDAT) { 362 Listnode * clist; 363 Is_desc * cisp; 364 365 for (LIST_TRAVERSE(&(osp->os_comdats), 366 clist, cisp)) { 367 if (strcmp(isp->is_basename, 368 cisp->is_basename)) 369 continue; 370 371 isp->is_flags |= FLG_IS_DISCARD; 372 isp->is_osdesc = osp; 373 DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml, 374 isp, cisp)); 375 return (0); 376 } 377 378 /* 379 * This is a new COMDAT section - so keep it. 380 */ 381 if (list_appendc(&(osp->os_comdats), isp) == 0) 382 return ((Os_desc *)S_ERROR); 383 } 384 385 /* 386 * Set alignment 387 */ 388 set_addralign(ofl, osp, isp); 389 390 /* 391 * If this section is a non-empty TLS section indicate 392 * that a PT_TLS program header is required. 393 */ 394 if ((shflags & SHF_TLS) && shdr->sh_size && 395 ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)) 396 ofl->ofl_flags |= FLG_OF_TLSPHDR; 397 398 /* 399 * If is_txtndx is 0 then this section was not 400 * seen in mapfile, so put it at the end. 401 * If is_txtndx is not 0 and ?O is turned on 402 * then check to see where this section should 403 * be inserted. 404 */ 405 if ((sgp->sg_flags & FLG_SG_ORDER) && isp->is_txtndx) { 406 Listnode * tlist; 407 408 tlist = list_where(&(osp->os_isdescs), 409 isp->is_txtndx); 410 if (tlist != NULL) { 411 if (list_insertc(&(osp->os_isdescs), 412 isp, tlist) == 0) 413 return ((Os_desc *)S_ERROR); 414 } else { 415 if (list_prependc(&(osp->os_isdescs), 416 isp) == 0) 417 return ((Os_desc *)S_ERROR); 418 } 419 } else 420 if (list_appendc(&(osp->os_isdescs), isp) == 0) 421 return ((Os_desc *)S_ERROR); 422 423 isp->is_osdesc = osp; 424 425 /* 426 * If this input section and file is associated to an 427 * artificially referenced output section, make sure 428 * they are marked as referenced also. This insures this 429 * input section and file isn't eliminated when -zignore 430 * is in effect. 431 * See -zignore comments when creating a new output 432 * section below. 433 */ 434 if (((ifl && 435 (ifl->ifl_flags & FLG_IF_IGNORE)) || DBG_ENABLED) && 436 (osp->os_flags & FLG_OS_SECTREF)) { 437 isp->is_flags |= FLG_IS_SECTREF; 438 if (ifl) 439 ifl->ifl_flags |= FLG_IF_FILEREF; 440 } 441 442 DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp)); 443 return (osp); 444 } 445 446 /* 447 * Do we need to worry about section ordering? 448 */ 449 if (os_ndx) { 450 if (osp->os_txtndx) { 451 if (os_ndx < osp->os_txtndx) 452 /* insert section here. */ 453 break; 454 else { 455 off2 = off1; 456 continue; 457 } 458 } else { 459 /* insert section here. */ 460 break; 461 } 462 } else if (osp->os_txtndx) { 463 off2 = off1; 464 continue; 465 } 466 467 /* 468 * If the new sections identifier is less than that of the 469 * present input section we need to insert the new section 470 * at this point. 471 */ 472 if (ident < osp->os_scnsymndx) 473 break; 474 475 off2 = off1; 476 } 477 478 /* 479 * We are adding a new output section. Update the section header 480 * count and associated string size. 481 */ 482 ofl->ofl_shdrcnt++; 483 if (st_insert(ofl->ofl_shdrsttab, isp->is_name) == -1) 484 return ((Os_desc *)S_ERROR); 485 486 /* 487 * Create a new output section descriptor. 488 */ 489 if ((osp = libld_calloc(sizeof (Os_desc), 1)) == 0) 490 return ((Os_desc *)S_ERROR); 491 if ((osp->os_shdr = libld_calloc(sizeof (Shdr), 1)) == 0) 492 return ((Os_desc *)S_ERROR); 493 494 /* 495 * We convert COMDAT sections to PROGBITS if this is the first 496 * section of a output section. 497 */ 498 if (shdr->sh_type == SHT_SUNW_COMDAT) { 499 Shdr * tshdr; 500 501 if ((tshdr = libld_malloc(sizeof (Shdr))) == 0) 502 return ((Os_desc *)S_ERROR); 503 *tshdr = *shdr; 504 isp->is_shdr = shdr = tshdr; 505 shdr->sh_type = SHT_PROGBITS; 506 if (list_appendc(&(osp->os_comdats), isp) == 0) 507 return ((Os_desc *)S_ERROR); 508 } 509 510 osp->os_shdr->sh_type = shdr->sh_type; 511 osp->os_shdr->sh_flags = shdr->sh_flags; 512 osp->os_shdr->sh_entsize = shdr->sh_entsize; 513 osp->os_name = isp->is_name; 514 osp->os_namehash = isp->is_namehash; 515 osp->os_txtndx = os_ndx; 516 osp->os_sgdesc = sgp; 517 518 if (ifl && (shdr->sh_type == SHT_PROGBITS)) { 519 /* 520 * Try to preserve the intended meaning of sh_link/sh_info. 521 * See the translate_link() in update.c. 522 */ 523 osp->os_shdr->sh_link = shdr->sh_link; 524 if (shdr->sh_flags & SHF_INFO_LINK) 525 osp->os_shdr->sh_info = shdr->sh_info; 526 } 527 528 /* 529 * When -zignore is in effect, user supplied sections and files that are 530 * not referenced from other sections, are eliminated from the object 531 * being produced. Some sections, although unreferenced, are special, 532 * and must not be eliminated. Determine if this new output section is 533 * one of those special sections, and if so mark it artificially as 534 * referenced. Any input section and file associated to this output 535 * section is also be marked as referenced, and thus won't be eliminated 536 * from the final output. 537 */ 538 if (ifl && ((ofl->ofl_flags1 & FLG_OF1_IGNPRC) || DBG_ENABLED)) { 539 const Msg *refsec; 540 541 for (refsec = RefSecs; *refsec; refsec++) { 542 if (strcmp(osp->os_name, MSG_ORIG(*refsec)) == 0) { 543 osp->os_flags |= FLG_OS_SECTREF; 544 545 if ((ifl->ifl_flags & FLG_IF_IGNORE) || 546 DBG_ENABLED) { 547 isp->is_flags |= FLG_IS_SECTREF; 548 ifl->ifl_flags |= FLG_IF_FILEREF; 549 } 550 break; 551 } 552 } 553 } 554 555 /* 556 * Setions of SHT_GROUP are added to the ofl->ofl_osgroups 557 * list - so that they can be updated as a group later. 558 */ 559 if (shdr->sh_type == SHT_GROUP) { 560 if (list_appendc(&ofl->ofl_osgroups, osp) == 0) 561 return ((Os_desc *)S_ERROR); 562 } 563 564 /* 565 * If this section is a non-empty TLS section indicate that a PT_TLS 566 * program header is required. 567 */ 568 if ((shflags & SHF_TLS) && shdr->sh_size && 569 ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)) 570 ofl->ofl_flags |= FLG_OF_TLSPHDR; 571 572 /* 573 * If a non-allocatable section is going to be put into a loadable 574 * segment then turn on the allocate bit for this section and warn the 575 * user that we have done so. This could only happen through the use 576 * of a mapfile. 577 */ 578 if ((sgp->sg_phdr.p_type == PT_LOAD) && 579 ((osp->os_shdr->sh_flags & SHF_ALLOC) == 0)) { 580 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SCN_NONALLOC), 581 ofl->ofl_name, osp->os_name); 582 osp->os_shdr->sh_flags |= SHF_ALLOC; 583 } 584 585 /* 586 * Retain this sections identifier for future comparisons when placing 587 * a section (after all sections have been processed this variable will 588 * be used to hold the sections symbol index as we don't need to retain 589 * the identifier any more). 590 */ 591 osp->os_scnsymndx = ident; 592 593 /* 594 * Set alignment 595 */ 596 set_addralign(ofl, osp, isp); 597 598 if (list_appendc(&(osp->os_isdescs), isp) == 0) 599 return ((Os_desc *)S_ERROR); 600 601 DBG_CALL(Dbg_sec_created(ofl->ofl_lml, osp, sgp)); 602 isp->is_osdesc = osp; 603 604 if (off2) { 605 /* 606 * Insert the new section after the section identified by off2. 607 */ 608 off2 += sizeof (Os_desc *); 609 if (alist_insert(&(sgp->sg_osdescs), &osp, 610 sizeof (Os_desc *), AL_CNT_OSDESC, off2) == 0) 611 return ((Os_desc *)S_ERROR); 612 } else { 613 /* 614 * Prepend this section to the section list. 615 */ 616 if (alist_insert(&(sgp->sg_osdescs), &osp, 617 sizeof (Os_desc *), AL_CNT_OSDESC, ALO_DATA) == 0) 618 return ((Os_desc *)S_ERROR); 619 } 620 return (osp); 621 } 622