xref: /netbsd-src/external/gpl3/gdb/dist/include/elf/reloc-macros.h (revision 02f41505626a9ceb584d30d0789203495760ac88)
198b9484cSchristos /* Generic relocation support for BFD.
2*02f41505Schristos    Copyright (C) 1998-2024 Free Software Foundation, Inc.
398b9484cSchristos 
498b9484cSchristos    This file is part of BFD, the Binary File Descriptor library.
598b9484cSchristos 
698b9484cSchristos    This program is free software; you can redistribute it and/or modify
798b9484cSchristos    it under the terms of the GNU General Public License as published by
898b9484cSchristos    the Free Software Foundation; either version 3 of the License, or
998b9484cSchristos    (at your option) any later version.
1098b9484cSchristos 
1198b9484cSchristos    This program is distributed in the hope that it will be useful,
1298b9484cSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1398b9484cSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1498b9484cSchristos    GNU General Public License for more details.
1598b9484cSchristos 
1698b9484cSchristos    You should have received a copy of the GNU General Public License
1798b9484cSchristos    along with this program; if not, write to the Free Software Foundation,
1898b9484cSchristos    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
1998b9484cSchristos 
2098b9484cSchristos /* These macros are used by the various *.h target specific header
2198b9484cSchristos    files to either generate an enum containing all the known relocations
2298b9484cSchristos    for that target, or if RELOC_MACROS_GEN_FUNC is defined, a recognition
2398b9484cSchristos    function is generated instead.  (This is used by binutils/readelf.c)
2498b9484cSchristos 
2598b9484cSchristos    Given a header file like this:
2698b9484cSchristos 
2798b9484cSchristos    	START_RELOC_NUMBERS (foo)
2898b9484cSchristos    	    RELOC_NUMBER (R_foo_NONE,    0)
2998b9484cSchristos    	    RELOC_NUMBER (R_foo_32,      1)
3098b9484cSchristos    	    EMPTY_RELOC  (R_foo_good)
3198b9484cSchristos    	    FAKE_RELOC   (R_foo_illegal, 9)
3298b9484cSchristos    	END_RELOC_NUMBERS (R_foo_count)
3398b9484cSchristos 
3498b9484cSchristos    Then the following will be produced by default (ie if
3598b9484cSchristos    RELOC_MACROS_GEN_FUNC is *not* defined).
3698b9484cSchristos 
3798b9484cSchristos    	enum foo
3898b9484cSchristos 	{
3998b9484cSchristos    	  R_foo_NONE = 0,
4098b9484cSchristos    	  R_foo_32 = 1,
4198b9484cSchristos 	  R_foo_good,
4298b9484cSchristos    	  R_foo_illegal = 9,
4398b9484cSchristos    	  R_foo_count
4498b9484cSchristos    	};
4598b9484cSchristos 
4698b9484cSchristos    Note: The value of the symbol defined in the END_RELOC_NUMBERS
4798b9484cSchristos    macro (R_foo_count in the case of the example above) will be
48a2e2270fSchristos    set to the value of the whichever *_RELOC macro precedes it plus
4998b9484cSchristos    one.  Therefore if you intend to use the symbol as a sentinel for
5098b9484cSchristos    the highest valid macro value you should make sure that the
51a2e2270fSchristos    preceding *_RELOC macro is the highest valid number.  ie a
5298b9484cSchristos    declaration like this:
5398b9484cSchristos 
5498b9484cSchristos    	START_RELOC_NUMBERS (foo)
5598b9484cSchristos    	    RELOC_NUMBER (R_foo_NONE,    0)
5698b9484cSchristos    	    RELOC_NUMBER (R_foo_32,      1)
5798b9484cSchristos    	    FAKE_RELOC   (R_foo_illegal, 9)
5898b9484cSchristos    	    FAKE_RELOC   (R_foo_synonym, 0)
5998b9484cSchristos    	END_RELOC_NUMBERS (R_foo_count)
6098b9484cSchristos 
6198b9484cSchristos    will result in R_foo_count having a value of 1 (R_foo_synonym + 1)
6298b9484cSchristos    rather than 10 or 2 as might be expected.
6398b9484cSchristos 
6498b9484cSchristos    Alternatively you can assign a value to END_RELOC_NUMBERS symbol
6598b9484cSchristos    explicitly, like this:
6698b9484cSchristos 
6798b9484cSchristos    	START_RELOC_NUMBERS (foo)
6898b9484cSchristos    	    RELOC_NUMBER (R_foo_NONE,    0)
6998b9484cSchristos    	    RELOC_NUMBER (R_foo_32,      1)
7098b9484cSchristos    	    FAKE_RELOC   (R_foo_illegal, 9)
7198b9484cSchristos    	    FAKE_RELOC   (R_foo_synonym, 0)
7298b9484cSchristos    	END_RELOC_NUMBERS (R_foo_count = 2)
7398b9484cSchristos 
7498b9484cSchristos    If RELOC_MACROS_GEN_FUNC *is* defined, then instead the
7598b9484cSchristos    following function will be generated:
7698b9484cSchristos 
7798b9484cSchristos    	static const char *foo (unsigned long rtype);
7898b9484cSchristos    	static const char *
7998b9484cSchristos    	foo (unsigned long rtype)
8098b9484cSchristos    	{
8198b9484cSchristos    	   switch (rtype)
8298b9484cSchristos    	   {
8398b9484cSchristos    	   case 0: return "R_foo_NONE";
8498b9484cSchristos    	   case 1: return "R_foo_32";
8598b9484cSchristos    	   default: return NULL;
8698b9484cSchristos    	   }
8798b9484cSchristos    	}
8898b9484cSchristos    */
8998b9484cSchristos 
9098b9484cSchristos #ifndef _RELOC_MACROS_H
9198b9484cSchristos #define _RELOC_MACROS_H
9298b9484cSchristos 
9398b9484cSchristos #ifdef RELOC_MACROS_GEN_FUNC
9498b9484cSchristos 
9598b9484cSchristos /* This function takes the relocation number and returns the
9698b9484cSchristos    string version name of the name of that relocation.  If
9798b9484cSchristos    the relocation is not recognised, NULL is returned.  */
9898b9484cSchristos 
9998b9484cSchristos #define START_RELOC_NUMBERS(name)   				\
10098b9484cSchristos static const char *name (unsigned long rtype);			\
10198b9484cSchristos static const char *						\
10298b9484cSchristos name (unsigned long rtype)					\
10398b9484cSchristos {								\
10498b9484cSchristos   switch (rtype)						\
10598b9484cSchristos     {
10698b9484cSchristos 
10798b9484cSchristos #define RELOC_NUMBER(name, number) \
10898b9484cSchristos     case number: return #name;
10998b9484cSchristos 
11098b9484cSchristos #define FAKE_RELOC(name, number)
11198b9484cSchristos #define EMPTY_RELOC(name)
11298b9484cSchristos 
11398b9484cSchristos #define END_RELOC_NUMBERS(name)	\
11498b9484cSchristos     default: return NULL;	\
11598b9484cSchristos     }				\
11698b9484cSchristos }
11798b9484cSchristos 
11898b9484cSchristos 
11998b9484cSchristos #else /* Default to generating enum.  */
12098b9484cSchristos 
12198b9484cSchristos #define START_RELOC_NUMBERS(name)   enum name {
12298b9484cSchristos #define RELOC_NUMBER(name, number)  name = number,
12398b9484cSchristos #define FAKE_RELOC(name, number)    name = number,
12498b9484cSchristos #define EMPTY_RELOC(name)           name,
12598b9484cSchristos #define END_RELOC_NUMBERS(name)     name };
12698b9484cSchristos 
12798b9484cSchristos #endif
12898b9484cSchristos 
12998b9484cSchristos #endif /* _RELOC_MACROS_H */
130