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 /* 56 * If this section has data or will be assigned data 57 * later, mark this segment not-empty. 58 */ 59 if ((shdr->sh_size != 0) || 60 ((isp->is_flags & FLG_IS_EXTERNAL) == 0)) 61 osp->os_sgdesc->sg_flags |= FLG_SG_PHREQ; 62 63 if ((ofl->ofl_flags1 & FLG_OF1_NOHDR) && 64 (osp->os_sgdesc->sg_phdr).p_type != PT_LOAD) 65 return; 66 67 osp->os_sgdesc->sg_addralign = 68 ld_lcm(osp->os_sgdesc->sg_addralign, shdr->sh_addralign); 69 } 70 71 /* 72 * Determine if section ordering is turned on. If so, return the appropriate 73 * os_txtndx. This information is derived from the Sg_desc->sg_segorder 74 * list that was built up from the Mapfile. 75 */ 76 static int 77 set_os_txtndx(Is_desc *isp, Sg_desc *sgp) 78 { 79 Listnode * lnp; 80 Sec_order * scop; 81 82 for (LIST_TRAVERSE(&sgp->sg_secorder, lnp, scop)) { 83 if (strcmp(scop->sco_secname, isp->is_name) == 0) { 84 scop->sco_flags |= FLG_SGO_USED; 85 return ((int)scop->sco_index); 86 } 87 } 88 return (0); 89 } 90 91 /* 92 * Place a section into the appropriate segment. 93 */ 94 Os_desc * 95 ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link) 96 { 97 Listnode * lnp1, * lnp2; 98 Ent_desc * enp; 99 Sg_desc * sgp; 100 Os_desc * osp; 101 int os_ndx; 102 Shdr * shdr = isp->is_shdr; 103 Xword shflagmask, shflags = shdr->sh_flags; 104 Ifl_desc * ifl = isp->is_file; 105 106 DBG_CALL(Dbg_sec_in(ofl->ofl_lml, isp)); 107 108 if ((shflags & SHF_GROUP) || (shdr->sh_type == SHT_GROUP)) { 109 Group_desc * gdesc; 110 111 if ((gdesc = ld_get_group(ofl, isp)) == (Group_desc *)S_ERROR) 112 return ((Os_desc *)S_ERROR); 113 114 if (gdesc) { 115 DBG_CALL(Dbg_sec_group(ofl->ofl_lml, isp, gdesc)); 116 117 /* 118 * If this group is marked as discarded, then this 119 * section needs to be discarded. 120 */ 121 if (gdesc->gd_flags & GRP_FLG_DISCARD) { 122 isp->is_flags |= FLG_IS_DISCARD; 123 return ((Os_desc *)0); 124 } 125 } 126 127 /* 128 * SHT_GROUP sections can only be included into relocatable 129 * objects. 130 */ 131 if (shdr->sh_type == SHT_GROUP) { 132 if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) { 133 isp->is_flags |= FLG_IS_DISCARD; 134 return ((Os_desc *)0); 135 } 136 } 137 } 138 139 /* 140 * Always assign SHF_TLS sections to the DATA segment (and then the 141 * PT_TLS embedded inside of there). 142 */ 143 if (shflags & SHF_TLS) 144 shflags |= SHF_WRITE; 145 146 /* 147 * Traverse the entrance criteria list searching for a segment that 148 * matches the input section we have. If an entrance criterion is set 149 * then there must be an exact match. If we complete the loop without 150 * finding a segment, then sgp will be NULL. 151 */ 152 sgp = NULL; 153 for (LIST_TRAVERSE(&ofl->ofl_ents, lnp1, enp)) { 154 if (enp->ec_segment && 155 (enp->ec_segment->sg_flags & FLG_SG_DISABLED)) 156 continue; 157 if (enp->ec_type && (enp->ec_type != shdr->sh_type)) 158 continue; 159 if (enp->ec_attrmask && 160 /* LINTED */ 161 (enp->ec_attrmask & enp->ec_attrbits) != 162 (enp->ec_attrmask & shflags)) 163 continue; 164 if (enp->ec_name && (strcmp(enp->ec_name, isp->is_name) != 0)) 165 continue; 166 if (enp->ec_files.head) { 167 char *file; 168 int found = 0; 169 170 if (isp->is_file == 0) 171 continue; 172 173 for (LIST_TRAVERSE(&(enp->ec_files), lnp2, file)) { 174 const char *name = isp->is_file->ifl_name; 175 176 if (file[0] == '*') { 177 const char *basename; 178 179 basename = strrchr(name, '/'); 180 if (basename == NULL) 181 basename = name; 182 else if (basename[1] != '\0') 183 basename++; 184 185 if (strcmp(&file[1], basename) == 0) { 186 found++; 187 break; 188 } 189 } else { 190 if (strcmp(file, name) == 0) { 191 found++; 192 break; 193 } 194 } 195 } 196 if (!found) 197 continue; 198 } 199 break; 200 } 201 202 if ((sgp = enp->ec_segment) == 0) 203 sgp = ((Ent_desc *)(ofl->ofl_ents.tail->data))->ec_segment; 204 205 isp->is_basename = isp->is_name; 206 207 /* 208 * Strip out the % from the section name in all cases except when '-r' 209 * is used without '-M', and '-r' is used with '-M' without 210 * the ?O flag. 211 */ 212 if (((ofl->ofl_flags & FLG_OF_RELOBJ) && 213 (sgp->sg_flags & FLG_SG_ORDER)) || 214 !(ofl->ofl_flags & FLG_OF_RELOBJ)) { 215 char *cp; 216 217 if ((cp = strchr(isp->is_name, '%')) != NULL) { 218 char *name; 219 size_t size = (size_t)(cp - isp->is_name); 220 221 if ((name = libld_malloc(size + 1)) == 0) 222 return ((Os_desc *)S_ERROR); 223 (void) strncpy(name, isp->is_name, size); 224 cp = name + size; 225 *cp = '\0'; 226 isp->is_name = name; 227 } 228 isp->is_txtndx = enp->ec_ndx; 229 } 230 231 /* 232 * Assign the is_namehash value now that we've settled 233 * on the final name for the section. 234 */ 235 isp->is_namehash = sgs_str_hash(isp->is_name); 236 237 if (sgp->sg_flags & FLG_SG_ORDER) 238 enp->ec_flags |= FLG_EC_USED; 239 240 /* 241 * If the link is not 0, then the isp is going to be appened 242 * to the output section where the input section pointed by 243 * link is placed. 244 */ 245 if (link != 0) { 246 osp = isp->is_file->ifl_isdesc[link]->is_osdesc; 247 /* 248 * If this is a COMDAT section, then see if this 249 * section is a keeper and/or if it is to be discarded. 250 */ 251 if (shdr->sh_type == SHT_SUNW_COMDAT) { 252 Listnode * clist; 253 Is_desc * cisp; 254 255 for (LIST_TRAVERSE(&(osp->os_comdats), clist, cisp)) { 256 if (strcmp(isp->is_basename, cisp->is_basename)) 257 continue; 258 259 isp->is_flags |= FLG_IS_DISCARD; 260 DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml, 261 isp, cisp)); 262 return (0); 263 } 264 265 /* 266 * This is a new COMDAT section - so keep it. 267 */ 268 if (list_appendc(&(osp->os_comdats), isp) == 0) 269 return ((Os_desc *)S_ERROR); 270 } 271 272 /* 273 * Set alignment 274 */ 275 set_addralign(ofl, osp, isp); 276 277 if (list_appendc(&(osp->os_isdescs), isp) == 0) 278 return ((Os_desc *)S_ERROR); 279 isp->is_osdesc = osp; 280 sgp = osp->os_sgdesc; 281 DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp)); 282 return (osp); 283 } 284 285 /* 286 * call the function set_os_txtndx() to set the 287 * os_txtndx field based upon the sg_segorder list that 288 * was built from a Mapfile. If there is no match then 289 * os_txtndx will be set to 0. 290 * 291 * for now this value will be held in os_ndx. 292 */ 293 os_ndx = set_os_txtndx(isp, sgp); 294 295 /* 296 * Setup the masks to flagout when matching sections 297 */ 298 shflagmask = ALL_SHF_ORDER; 299 if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) 300 shflagmask = ALL_SHF_IGNORE; 301 302 /* 303 * Traverse the input section list for the output section we have been 304 * assigned. If we find a matching section simply add this new section. 305 */ 306 lnp2 = NULL; 307 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp1, osp)) { 308 Shdr * _shdr = osp->os_shdr; 309 310 if ((ident == osp->os_scnsymndx) && 311 (shdr->sh_type != SHT_SUNW_dof) && 312 ((shdr->sh_type == _shdr->sh_type) || 313 ((shdr->sh_type == SHT_SUNW_COMDAT) && 314 (_shdr->sh_type == SHT_PROGBITS))) && 315 ((shflags & ~shflagmask) == 316 (_shdr->sh_flags & ~shflagmask)) && 317 (ident != M_ID_REL) && (shdr->sh_type != SHT_GROUP) && 318 (isp->is_namehash == osp->os_namehash) && 319 (strcmp(isp->is_name, osp->os_name) == 0)) { 320 /* 321 * If this is a COMDAT section, then see if this 322 * section is a keeper and/or if it is to 323 * be discarded. 324 */ 325 if (shdr->sh_type == SHT_SUNW_COMDAT) { 326 Listnode * clist; 327 Is_desc * cisp; 328 329 for (LIST_TRAVERSE(&(osp->os_comdats), 330 clist, cisp)) { 331 if (strcmp(isp->is_basename, 332 cisp->is_basename)) 333 continue; 334 335 isp->is_flags |= FLG_IS_DISCARD; 336 DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml, 337 isp, cisp)); 338 return (0); 339 } 340 341 /* 342 * This is a new COMDAT section - so keep it. 343 */ 344 if (list_appendc(&(osp->os_comdats), isp) == 0) 345 return ((Os_desc *)S_ERROR); 346 } 347 348 /* 349 * Set alignment 350 */ 351 set_addralign(ofl, osp, isp); 352 353 /* 354 * If this section is a non-empty TLS section indicate 355 * that a PT_TLS program header is required. 356 */ 357 if ((shflags & SHF_TLS) && shdr->sh_size && 358 ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)) 359 ofl->ofl_flags |= FLG_OF_TLSPHDR; 360 361 /* 362 * If is_txtndx is 0 then this section was not 363 * seen in mapfile, so put it at the end. 364 * If is_txtndx is not 0 and ?O is turned on 365 * then check to see where this section should 366 * be inserted. 367 */ 368 if ((sgp->sg_flags & FLG_SG_ORDER) && isp->is_txtndx) { 369 Listnode * tlist; 370 371 tlist = list_where(&(osp->os_isdescs), 372 isp->is_txtndx); 373 if (tlist != NULL) { 374 if (list_insertc(&(osp->os_isdescs), 375 isp, tlist) == 0) 376 return ((Os_desc *)S_ERROR); 377 } else { 378 if (list_prependc(&(osp->os_isdescs), 379 isp) == 0) 380 return ((Os_desc *)S_ERROR); 381 } 382 } else 383 if (list_appendc(&(osp->os_isdescs), isp) == 0) 384 return ((Os_desc *)S_ERROR); 385 386 isp->is_osdesc = osp; 387 388 /* 389 * If this input section and file is associated to an 390 * artificially referenced output section, make sure 391 * they are marked as referenced also. This insures this 392 * input section and file isn't eliminated when -zignore 393 * is in effect. 394 * See -zignore comments when creating a new output 395 * section below. 396 */ 397 if (((ifl && (ifl->ifl_flags & FLG_IF_IGNORE)) || 398 DBG_ENABLED) && 399 (osp->os_flags & FLG_OS_SECTREF)) { 400 isp->is_flags |= FLG_IS_SECTREF; 401 if (ifl) 402 ifl->ifl_flags |= FLG_IF_FILEREF; 403 } 404 405 DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp)); 406 return (osp); 407 } 408 409 /* 410 * check to see if we need to worry about section 411 * ordering. 412 */ 413 if (os_ndx) { 414 if (osp->os_txtndx) { 415 if (os_ndx < osp->os_txtndx) 416 /* insert section here. */ 417 break; 418 else { 419 lnp2 = lnp1; 420 continue; 421 } 422 } else { 423 /* insert section here. */ 424 break; 425 } 426 } else if (osp->os_txtndx) { 427 lnp2 = lnp1; 428 continue; 429 } 430 431 /* 432 * If the new sections identifier is less than that of the 433 * present input section we need to insert the new section 434 * at this point. 435 */ 436 if (ident < osp->os_scnsymndx) 437 break; 438 lnp2 = lnp1; 439 } 440 441 /* 442 * We are adding a new output section. Update the section header 443 * count and associated string size. 444 */ 445 ofl->ofl_shdrcnt++; 446 if (st_insert(ofl->ofl_shdrsttab, isp->is_name) == -1) 447 return ((Os_desc *)S_ERROR); 448 449 /* 450 * Create a new output section descriptor. 451 */ 452 if ((osp = libld_calloc(sizeof (Os_desc), 1)) == 0) 453 return ((Os_desc *)S_ERROR); 454 if ((osp->os_shdr = libld_calloc(sizeof (Shdr), 1)) == 0) 455 return ((Os_desc *)S_ERROR); 456 457 /* 458 * We convert COMDAT sections to PROGBITS if this is the first 459 * section of a output section. 460 */ 461 if (shdr->sh_type == SHT_SUNW_COMDAT) { 462 Shdr * tshdr; 463 464 if ((tshdr = libld_malloc(sizeof (Shdr))) == 0) 465 return ((Os_desc *)S_ERROR); 466 *tshdr = *shdr; 467 isp->is_shdr = shdr = tshdr; 468 shdr->sh_type = SHT_PROGBITS; 469 if (list_appendc(&(osp->os_comdats), isp) == 0) 470 return ((Os_desc *)S_ERROR); 471 } 472 473 osp->os_shdr->sh_type = shdr->sh_type; 474 osp->os_shdr->sh_flags = shdr->sh_flags; 475 osp->os_shdr->sh_entsize = shdr->sh_entsize; 476 osp->os_name = isp->is_name; 477 osp->os_namehash = isp->is_namehash; 478 osp->os_txtndx = os_ndx; 479 osp->os_sgdesc = sgp; 480 if (ifl && (shdr->sh_type == SHT_PROGBITS)) { 481 /* 482 * Trying to preserved the possibly intended meaning of 483 * sh_link/sh_info. See the translate_link() 484 * in update.c. 485 */ 486 osp->os_shdr->sh_link = shdr->sh_link; 487 if (shdr->sh_flags & SHF_INFO_LINK) 488 osp->os_shdr->sh_info = shdr->sh_info; 489 } 490 491 /* 492 * When -zignore is in effect, sections and files that are not 493 * referenced * from other sections, will be eliminated from the 494 * object being produced. Some sections, although unreferenced, 495 * are special, and must not be eliminated. Determine if this new 496 * output section is one of those special sections, and if so mark 497 * it artificially as referenced. 498 * Any input section and file associated to this output section 499 * will also be marked as referenced, and thus won't be eliminated 500 * from the final output. 501 */ 502 if ((strcmp(osp->os_name, MSG_ORIG(MSG_SCN_INIT)) == 0) || 503 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_FINI)) == 0) || 504 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_EX_RANGES)) == 0) || 505 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_EX_SHARED)) == 0) || 506 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_CTORS)) == 0) || 507 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_DTORS)) == 0) || 508 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_EHFRAME)) == 0) || 509 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_EHFRAME_HDR)) == 0) || 510 (strcmp(osp->os_name, MSG_ORIG(MSG_SCN_JCR)) == 0)) { 511 osp->os_flags |= FLG_OS_SECTREF; 512 513 if ((ifl && (ifl->ifl_flags & FLG_IF_IGNORE)) || DBG_ENABLED) { 514 isp->is_flags |= FLG_IS_SECTREF; 515 if (ifl) 516 ifl->ifl_flags |= FLG_IF_FILEREF; 517 } 518 } 519 520 /* 521 * Setions of SHT_GROUP are added to the ofl->ofl_osgroups 522 * list - so that they can be updated as a group later. 523 */ 524 if (shdr->sh_type == SHT_GROUP) { 525 if (list_appendc(&ofl->ofl_osgroups, osp) == 0) 526 return ((Os_desc *)S_ERROR); 527 } 528 529 /* 530 * If this section is a non-empty TLS section indicate that a PT_TLS 531 * program header is required. 532 */ 533 if ((shflags & SHF_TLS) && shdr->sh_size && 534 ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)) 535 ofl->ofl_flags |= FLG_OF_TLSPHDR; 536 537 /* 538 * If a non-allocatable section is going to be put into a loadable 539 * segment then turn on the allocate bit for this section and warn the 540 * user that we have done so. This could only happen through the use 541 * of a mapfile. 542 */ 543 if (sgp->sg_phdr.p_type == PT_LOAD) { 544 if (!(osp->os_shdr->sh_flags & SHF_ALLOC)) { 545 eprintf(ofl->ofl_lml, ERR_WARNING, 546 MSG_INTL(MSG_SCN_NONALLOC), ofl->ofl_name, 547 osp->os_name); 548 osp->os_shdr->sh_flags |= SHF_ALLOC; 549 } 550 } 551 552 /* 553 * Retain this sections identifier for future comparisons when placing 554 * a section (after all sections have been processed this variable will 555 * be used to hold the sections symbol index as we don't need to retain 556 * the identifier any more). 557 */ 558 osp->os_scnsymndx = ident; 559 560 /* 561 * Set alignment 562 */ 563 set_addralign(ofl, osp, isp); 564 565 if (list_appendc(&(osp->os_isdescs), isp) == 0) 566 return ((Os_desc *)S_ERROR); 567 568 DBG_CALL(Dbg_sec_created(ofl->ofl_lml, osp, sgp)); 569 isp->is_osdesc = osp; 570 if (lnp2) { 571 if (list_insertc(&(sgp->sg_osdescs), osp, lnp2) == 0) 572 return ((Os_desc *)S_ERROR); 573 } else { 574 if (list_prependc(&(sgp->sg_osdescs), osp) == 0) 575 return ((Os_desc *)S_ERROR); 576 } 577 return (osp); 578 } 579