[IAR]how can i printf a section start of end address? - attributes

1.I create a custom section for myTest in .icf
define symbol __ICFEDIT_region_TEST_start__ = (0x10080000);
define symbol __ICFEDIT_region_TEST_end__ = (0x100DFFFF);
define region TEST_region = mem:[from __ICFEDIT_region_TEST_start__ to __ICFEDIT_region_TEST_end__];
place at start of TEST_region {section .test_cases_entries};
2.I code some test in test.c
#pragma section = ".test_cases_entries"
void pfm_test_cases_init(void)
{
struct pwb_altest_desc *start,*stop;
start = __section_begin(".test_cases_entries");
stop = __section_end(".test_cases_entries");
printf("test section start = %x \n\r",start);
printf("test section end = %x \n\r",stop);
}
result the response
test section start = 0
test section end = 0
expect result: start of section 0x10080000? end of section 0x100DFFFF?

__section_begin(".section") and __section_end(".section") will be 0 if no part of the section .section is included in the final binary. In your case you first must ensure that the section .test_case_entries is not empty, i.e some module in you project put data in this section. Then you need to make the linker include this data in the final binary. This is either done by making a reference to the data in some module (__section_begin and __section_end does not count), declare the data as __root, or by using --keep on the linker command line.
An test program that works on my machine is included below. Note that the .icf file is not complete as most of it depends on your target system.
test.c:
#include <stdio.h>
// Make the compiler recognize .section as a section for __section_begin and
// __section_end.
#pragma section = ".section"
void main(void)
{
// Find the start and end address of .section
int *start = __section_begin(".section");
int *stop = __section_end(".section");
printf("section start = %x \n", start);
printf("section end = %x \n", stop);
}
// Put data in .section and make the data root to ensure is is included.
// This can be in a different file.
#pragma location=".section"
__root int data[100];
Part of test.icf
define symbol TEST_start = (0x10080000);
define symbol TEST_end = (0x100DFFFF);
define region TEST_region = mem:[from TEST_start to TEST_end];
place at start of TEST_region {section .section};

Related

Why does this code works well? It changes the Constant storage area string;

this is a simple linux kernel module code to reverse a string which should Oops after insmod,but it works well,why?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static char *words = "words";
static int __init words_init(void)
{
printk(KERN_INFO "debug info\n");
int len = strlen(words);
int k;
for ( k = 0; k < len/2; k++ )
{
printk("the value of k %d\n",k);
char a = words[k];
words[k]= words[len-1-k];
words[len-1-k]=a;
}
printk(KERN_INFO "words is %s\n", words);
return 0;
}
static void __exit words_exit(void)
{
printk(KERN_INFO "words exit.\n");
}
module_init(words_init);
module_exit(words_exit);
module_param(words, charp, S_IRUGO);
MODULE_LICENSE("GPL");
static != const.
static in your example means "only visible in the current file". See What does "static" mean?
const just means "the code which can see this declaration isn't supposed to change the variable". But in certain cases, you can still create a non-const pointer to the same address and modify the contents.
Space removal from a String - In Place C style with Pointers suggests that writing to the string value shouldn't be possible.
Since static is the only difference between your code and that of the question, I looked further and found this: Global initialized variables declared as "const" go to text segment, while those declared "Static" go to data segment. Why?
Try static const char *word, that should do the trick.
Haha!,I get the answer from the linux kernel source code by myself;When you use the insmod,it will call the init_moudle,load_module,strndup_usr then memdup_usr function;the memdup_usr function will use kmalloc_track_caller to alloc memery from slab and then use the copy_from_usr to copy the module paragram into kernel;this mean the linux kernel module paragram store in heap,not in the constant storage area!! So we can change it's content!

(Optimization?) Bug regarding GCC std::thread

While testing some functionality with std::thread, a friend encountered a problem with GCC and we thought it's worth asking if this is a GCC bug or perhaps there's something wrong with this code (the code prints (for example) "7 8 9 10 1 2 3", but we expect every integer in [1,10] to be printed):
#include <algorithm>
#include <iostream>
#include <iterator>
#include <thread>
int main() {
int arr[10];
std::iota(std::begin(arr), std::end(arr), 1);
using itr_t = decltype(std::begin(arr));
// the function that will display each element
auto f = [] (itr_t first, itr_t last) {
while (first != last) std::cout<<*(first++)<<' ';};
// we have 3 threads so we need to figure out the ranges for each thread to show
int increment = std::distance(std::begin(arr), std::end(arr)) / 3;
auto first = std::begin(arr);
auto to = first + increment;
auto last = std::end(arr);
std::thread threads[3] = {
std::thread{f, first, to},
std::thread{f, (first = to), (to += increment)},
std::thread{f, (first = to), last} // go to last here to account for odd array sizes
};
for (auto&& t : threads) t.join();
}
The following alternate code works:
int main()
{
std::array<int, 10> a;
std::iota(a.begin(), a.end(), 1);
using iter_t = std::array<int, 10>::iterator;
auto dist = std::distance( a.begin(), a.end() )/3;
auto first = a.begin(), to = first + dist, last = a.end();
std::function<void(iter_t, iter_t)> f =
[]( iter_t first, iter_t last ) {
while ( first != last ) { std::cout << *(first++) << ' '; }
};
std::thread threads[] {
std::thread { f, first, to },
std::thread { f, to, to + dist },
std::thread { f, to + dist, last }
};
std::for_each(
std::begin(threads),std::end(threads),
std::mem_fn(&std::thread::join));
return 0;
}
We thought maybe its got something to do with the unsequenced evaluation of function's arity or its just the way std::thread is supposed to work when copying non-std::ref-qualified arguments. We then tested the first code with Clang and it works (and so started to suspect a GCC bug).
Compiler used: GCC 4.7, Clang 3.2.1
EDIT: The GCC code gives the wrong output with the first version of the code, but with the second version it gives the correct output.
From this modified program:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <thread>
#include <sstream>
int main()
{
int arr[10];
std::iota(std::begin(arr), std::end(arr), 1);
using itr_t = decltype(std::begin(arr));
// the function that will display each element
auto f = [] (itr_t first, itr_t last) {
std::stringstream ss;
ss << "**Pointer:" << first << " | " << last << std::endl;
std::cout << ss.str();
while (first != last) std::cout<<*(first++)<<' ';};
// we have 3 threads so we need to figure out the ranges for each thread to show
int increment = std::distance(std::begin(arr), std::end(arr)) / 3;
auto first = std::begin(arr);
auto to = first + increment;
auto last = std::end(arr);
std::thread threads[3] = {
std::thread{f, first, to},
#ifndef FIX
std::thread{f, (first = to), (to += increment)},
std::thread{f, (first = to), last} // go to last here to account for odd array sizes
#else
std::thread{f, to, to+increment},
std::thread{f, to+increment, last} // go to last here to account for odd array sizes
#endif
};
for (auto&& t : threads) {
t.join();
}
}
I add the prints of the first and last pointer for lambda function f, and find this interesting results (when FIX is undefined):
**Pointer:0x28abd8 | 0x28abe4
1 2 3 **Pointer:0x28abf0 | 0x28abf0
**Pointer:0x28abf0 | 0x28ac00
7 8 9 10
Then I add some code for the #ELSE case for the #ifndef FIX. It works well.
- Update: This conclusion, the original post below, is wrong. My fault. See Josh's comment below -
I believe the 2nd line std::thread{f, (first = to), (to +=
increment)}, of threads[] contains a bug: The assignment inside the
two pairs of parenthesis, can be evaluated in any order, by the
parser. Yet the assignment order of 1st, 2nd and 3rd argument of the
constructor needs to keep the order as given.
--- Update: corrected ---
Thus the above debug printing results suggest that GCC4.8.2 (my version)
is still buggy (not to say GCC4.7), but GCC 4.9.2 fixes this bug, as
reported by Maxim Yegorushkin (see comment above).

lsmod showing module is used by -2

I am trying to pass command line parameters using following code
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
static int nilvar=0;
static int nilvar2=0;
int rollcalls[5];// = {0};
char classname[10];// = "math";
module_param_named (var,nilvar2,int,0644);
module_param (nilvar,int,0644);
module_param_array_named(present,rollcalls,int,5,0644);
module_param_string(subject,classname,10,0644);
int init_module(void)
{
printk(KERN_INFO"1) nilvar = %d\n 2) nilvar2 = %d",nilvar,nilvar2);
printk(KERN_INFO/*NOTICE*/"ROLLCALLS = %d ,%d ,%d ,%d",rollcalls[0],rollcalls[1],rollcalls[2],rollcalls[3]);
printk(KERN_INFO/*DEBUG*/"classname = %s",classname);
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Bye....\n");
}
MODULE_LICENSE("GPL");
after make ,I am passing my arguments by
insmod module1.ko var=5 nilvar=6 present=1 2 3 4 subject=physics
I don't know exactly what is happening but now lsmod shows module used by -2.
(actually no module is dependent on this module)
so where I am wrong ? and if we want to modify all this variables as a structure elements, then how to use module_param() macro for it?
#user3452214, instead of module_param_array_named(present, rollcalls, int, **5**, 0644); use module_param_array_named(present, rollcalls, int, **&count**, 0644); added one more variable i.e. static unsigned int count which keep count of the number written to the array. We need to pass the pointer as explained in the moduleparam.h, thus cannot pass numerical value for this parameter. It works fine!!!. Hope it solves your problem.
/**
* module_param_array_named - renamed parameter which is an array of some type
* #name: a valid C identifier which is the parameter name
* #array: the name of the array variable
* #type: the type, as per module_param()
* #nump: optional pointer filled in with the number written
* #perm: visibility in sysfs
*
* This exposes a different name than the actual variable name. See
* module_param_named() for why this might be necessary.
*/
#define module_param_array_named(name, array, type, nump, perm)

can a program read its own elf section?

I would like to use ld's --build-id option in order to add build information to my binary. However, I'm not sure how to make this information available inside the program. Assume I want to write a program that writes a backtrace every time an exception occurs, and a script that parses this information. The script reads the symbol table of the program and searches for the addresses printed in the backtrace (I'm forced to use such a script because the program is statically linked and backtrace_symbols is not working). In order for the script to work correctly I need to match build version of the program with the build version of the program which created the backtrace. How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?
How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?
You need to read the ElfW(Ehdr) (at the beginning of the file) to find program headers in your binary (.e_phoff and .e_phnum will tell you where program headers are, and how many of them to read).
You then read program headers, until you find PT_NOTE segment of your program. That segment will tell you offset to the beginning of all the notes in your binary.
You then need to read the ElfW(Nhdr) and skip the rest of the note (total size of the note is sizeof(Nhdr) + .n_namesz + .n_descsz, properly aligned), until you find a note with .n_type == NT_GNU_BUILD_ID.
Once you find NT_GNU_BUILD_ID note, skip past its .n_namesz, and read the .n_descsz bytes to read the actual build-id.
You can verify that you are reading the right data by comparing what you read with the output of readelf -n a.out.
P.S.
If you are going to go through the trouble to decode build-id as above, and if your executable is not stripped, it may be better for you to just decode and print symbol names instead (i.e. to replicate what backtrace_symbols does) -- it's actually easier to do than decoding ELF notes, because the symbol table contains fixed-sized entries.
Basically, this is the code I've written based on answer given to my question. In order to compile the code I had to make some changes and I hope it will work for as many types of platforms as possible. However, it was tested only on one build machine. One of the assumptions I used was that the program was built on the machine which runs it so no point in checking endianness compatibility between the program and the machine.
user#:~/$ uname -s -r -m -o
Linux 3.2.0-45-generic x86_64 GNU/Linux
user#:~/$ g++ test.cpp -o test
user#:~/$ readelf -n test | grep Build
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
user#:~/$ ./test
Build ID: dc5c4682e0282e2bd8bc2d3b61cfe35826aa34fc
#include <elf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#if __x86_64__
# define ElfW(type) Elf64_##type
#else
# define ElfW(type) Elf32_##type
#endif
/*
detecting build id of a program from its note section
http://stackoverflow.com/questions/17637745/can-a-program-read-its-own-elf-section
http://www.scs.stanford.edu/histar/src/pkg/uclibc/utils/readelf.c
http://www.sco.com/developers/gabi/2000-07-17/ch5.pheader.html#note_section
*/
int main (int argc, char* argv[])
{
char *thefilename = argv[0];
FILE *thefile;
struct stat statbuf;
ElfW(Ehdr) *ehdr = 0;
ElfW(Phdr) *phdr = 0;
ElfW(Nhdr) *nhdr = 0;
if (!(thefile = fopen(thefilename, "r"))) {
perror(thefilename);
exit(EXIT_FAILURE);
}
if (fstat(fileno(thefile), &statbuf) < 0) {
perror(thefilename);
exit(EXIT_FAILURE);
}
ehdr = (ElfW(Ehdr) *)mmap(0, statbuf.st_size,
PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(thefile), 0);
phdr = (ElfW(Phdr) *)(ehdr->e_phoff + (size_t)ehdr);
while (phdr->p_type != PT_NOTE)
{
++phdr;
}
nhdr = (ElfW(Nhdr) *)(phdr->p_offset + (size_t)ehdr);
while (nhdr->n_type != NT_GNU_BUILD_ID)
{
nhdr = (ElfW(Nhdr) *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz + nhdr->n_descsz);
}
unsigned char * build_id = (unsigned char *)malloc(nhdr->n_descsz);
memcpy(build_id, (void *)((size_t)nhdr + sizeof(ElfW(Nhdr)) + nhdr->n_namesz), nhdr->n_descsz);
printf(" Build ID: ");
for (int i = 0 ; i < nhdr->n_descsz ; ++i)
{
printf("%02x",build_id[i]);
}
free(build_id);
printf("\n");
return 0;
}
Yes, a program can read its own .note.gnu.build-id. The important piece is the dl_iterate_phdr function.
I've used this technique in Mesa (the OpenGL/Vulkan implementation) to read its own build-id for use with the on-disk shader cache.
I've extracted those bits into a separate project[1] for easy use by others.
[1] https://github.com/mattst88/build-id

Why does a C++ string not appear to have been initialized correctly when seen through the output of "print" in GDB?

I have the following piece of code.
#include <string>
#include <ctype.h>
std::string lowerCase(const std::string &exprName)
{
std::string dummy(exprName);
char firstChar = tolower(exprName.at(0));
dummy.replace(0, 1, &firstChar);
return dummy;
}
When I step through the code using GDB, and break at line 6 (std::string dummy(exprName)), I expect dummy to be empty. But when I print it using
p dummy
GDB prints a value for the variable in the following way
Breakpoint 1, lowerCase (exprName=...) at Utility.cpp:49
49 std::string dummy("");
(gdb) print dummy
$1 = {
static npos = 18446744073709551615,
_M_dataplus = {
<std::allocator<char>> = {
<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
members of std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider:
_M_p = 0x634261 "Expr * input2 = facade->derefE(facade->varE(v));\nNode * subject = f->"
}
}
Also, if I step to the next line of code, i.e.
char firstChar = tolower(exprName.at(0));
and I print the value of "dummy" in GDB, it's value remains the same and doesn't change to the value of exprName. I printed "exprName" and it definitely contains a different value!
This is baffling! Why would dummy not be initialized to the same value as that of exprName?
That is exactly what uninitialized means: the value is (sort of) unpredictable, and when you look at the contents, it is likely to not make sense.
In your case the _M_ptr pointer accidentally happens to point into a valid memory range, so you do see something which looks like a string. The contents depend on values temporarily stored on the stack by another function, called before this one.

Resources