xref: /freebsd/contrib/elftoolchain/libpe/pe_symtab.c (revision 388586bcd883f622752ec8ddfeb1b58f447c46d2)
1839529caSEd Maste /*-
2839529caSEd Maste  * Copyright (c) 2016 Kai Wang
3839529caSEd Maste  * All rights reserved.
4839529caSEd Maste  *
5839529caSEd Maste  * Redistribution and use in source and binary forms, with or without
6839529caSEd Maste  * modification, are permitted provided that the following conditions
7839529caSEd Maste  * are met:
8839529caSEd Maste  * 1. Redistributions of source code must retain the above copyright
9839529caSEd Maste  *    notice, this list of conditions and the following disclaimer.
10839529caSEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
11839529caSEd Maste  *    notice, this list of conditions and the following disclaimer in the
12839529caSEd Maste  *    documentation and/or other materials provided with the distribution.
13839529caSEd Maste  *
14839529caSEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15839529caSEd Maste  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16839529caSEd Maste  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17839529caSEd Maste  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18839529caSEd Maste  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19839529caSEd Maste  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20839529caSEd Maste  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21839529caSEd Maste  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22839529caSEd Maste  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23839529caSEd Maste  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24839529caSEd Maste  * SUCH DAMAGE.
25839529caSEd Maste  */
26839529caSEd Maste 
27839529caSEd Maste #include <errno.h>
28839529caSEd Maste 
29839529caSEd Maste #include "_libpe.h"
30839529caSEd Maste 
31839529caSEd Maste ELFTC_VCSID("$Id: pe_symtab.c 3312 2016-01-10 09:23:51Z kaiwang27 $");
32839529caSEd Maste 
33839529caSEd Maste int
pe_update_symtab(PE * pe,char * symtab,size_t sz,unsigned int nsym)34839529caSEd Maste pe_update_symtab(PE *pe, char *symtab, size_t sz, unsigned int nsym)
35839529caSEd Maste {
36*388586bcSMark Johnston 	PE_Scn *ps, *pstmp;
37839529caSEd Maste 	PE_SecBuf *sb;
38839529caSEd Maste 	PE_SecHdr *sh;
39839529caSEd Maste 
40839529caSEd Maste 	if (pe == NULL || symtab == NULL || sz == 0) {
41839529caSEd Maste 		errno = EINVAL;
42839529caSEd Maste 		return (-1);
43839529caSEd Maste 	}
44839529caSEd Maste 
45839529caSEd Maste 	if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) {
46839529caSEd Maste 		errno = EACCES;
47839529caSEd Maste 		return (-1);
48839529caSEd Maste 	}
49839529caSEd Maste 
50839529caSEd Maste 	/* Remove the old symbol table. */
51*388586bcSMark Johnston 	STAILQ_FOREACH_SAFE(ps, &pe->pe_scn, ps_next, pstmp) {
52839529caSEd Maste 		if (ps->ps_ndx == 0xFFFFFFFFU)
53839529caSEd Maste 			libpe_release_scn(ps);
54839529caSEd Maste 	}
55839529caSEd Maste 
56839529caSEd Maste 	/*
57839529caSEd Maste 	 * Insert the new symbol table.
58839529caSEd Maste 	 */
59839529caSEd Maste 
60839529caSEd Maste 	if ((ps = libpe_alloc_scn(pe)) == NULL)
61839529caSEd Maste 		return (-1);
62839529caSEd Maste 
63839529caSEd Maste 	STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next);
64839529caSEd Maste 	ps->ps_ndx = 0xFFFFFFFFU;
65839529caSEd Maste 	ps->ps_flags |= PE_F_DIRTY;
66839529caSEd Maste 
67839529caSEd Maste 	/*
68839529caSEd Maste 	 * Set the symbol table section offset to the maximum to make sure
69839529caSEd Maste 	 * that it will be placed in the end of the file during section
70839529caSEd Maste 	 * layout.
71839529caSEd Maste 	 */
72839529caSEd Maste 	sh = &ps->ps_sh;
73839529caSEd Maste 	sh->sh_rawptr = 0xFFFFFFFFU;
74839529caSEd Maste 	sh->sh_rawsize = sz;
75839529caSEd Maste 
76839529caSEd Maste 	/* Allocate the buffer. */
77839529caSEd Maste 	if ((sb = libpe_alloc_buffer(ps, 0)) == NULL)
78839529caSEd Maste 		return (-1);
79839529caSEd Maste 	sb->sb_flags |= PE_F_DIRTY;
80839529caSEd Maste 	sb->sb_pb.pb_size = sz;
81839529caSEd Maste 	sb->sb_pb.pb_buf = symtab;
82839529caSEd Maste 
83839529caSEd Maste 	pe->pe_nsym = nsym;
84839529caSEd Maste 
85839529caSEd Maste 	return (0);
86839529caSEd Maste }
87