Cross compiling for arm gcc5 - Proper use of memcpy - c++

I am trying to compile a kernel (uImage) for the S805/S812 SoC from amlogic. I have managed to solve all compilation error except for one, probably because my knowledge of c++ and compilers don't reach far enough. Let me explain the problem, which exist in a file phydev.c :
The line giving the error is :
memcpy(&phydev->name, &dev_para->name, MAX_DEVICE_NAME_LEN*sizeof(char));
These are the (cross)compiler errors:
drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/phydev.c: In function ‘amlnand_phydev_init’:
drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/phydev.c:1114:10: error: passing argument 1 of ‘memcpy’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-array-qualifiers]
memcpy(&phydev->name, &dev_para->name, MAX_DEVICE_NAME_LEN*sizeof(char));
^
In file included from include/linux/string.h:17:0,
from include/linux/dynamic_debug.h:111,
from include/linux/kernel.h:14,
from include/linux/cache.h:4,
from include/linux/time.h:4,
from include/linux/stat.h:18,
from include/linux/module.h:10,
from drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/../include/../include/amlnf_type.h:18,
from drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/../include/../include/amlnf_dev.h:4,
from drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/../include/phynand.h:4,
from drivers/amlogic/../../../hardware/amlogic/nand/amlnf/dev/phydev.c:14:
/root/Downloads/Beelink3/arm-src-kernel-2015-01-15-321cfb5a46/arch/arm/include/asm/string.h:16:15:
note: expected ‘void *’ but argument is of type ‘const char (*)[16]’
extern void * memcpy(void *, const void *, __kernel_size_t);
^
I have been trying to figure this out for several days, also trying direct assignment (which obviously doesn't work on arrays), using strcpy instead and so on, but this only yields more errors and I can't find the exact root cause. I think I need some kind of cast or intermediate constant void ptr but I have no clue how to fix this.
Could anyone be as kind as to give me advice on this and how to solve it. The memcpy function is defined in arch/arm/include/asm/string.h
But it did not seem a good idea messing with this file.
Many thanks,
Wim

Indeed someone had been smart enough to :
Struct phydev {
const char* name;
...
Removed the const and all was fine (at least the memcpy line. But I could use strcpy or strdup or whatever. It was trying to write to a constant.
After debugging trough all of the other errors I was able to make the U-Boot Image. Haven't tested it yet.
Also, made a lot of functions static instead of copying used static variables into local attributes. Don't know what it's gonna do... (probably crash with some segmentation fault or something:-).
I'll have to wait for my ttl usb adapter now...
Unless anyone know where to find an adb driver for this thing and it supports fw_setenv or something....
Guess it will be pressing the space bar on tty1 once the ttl adapter arrives.
Thanks guys for all your help. If I manage to get Ubuntu on this box I'll post a blog about it :-)
Cheers & thanks
Wim

Related

Transfering v8 types to c++ types (string)

I am making a c++ addon for node.js and I am struggling with passing and getting data. I understood how to transform v8::Number to double, double to v8::Number and int to v8:Number, but I need some more. Mainly, v8::String to std::string and back, v8::Number to int and v8::Array to Array and back. Also it would be great to transfer js objects to some c++ variables, but it is less necessary. Does someone know, how to do that?
P.S. I looked over docs and I found nothing about arrays and objects and only this string a (*v8::String::Utf8Value(args[0]->ToString())) according to strings. But it does not work, I get an error error C2660: v8::Value::ToString: function does not get 0 arguments and error C2512: v8::String::Utf8Value: no suitable default constructor. I do not have any more ideas how to implement that. Can someone help?
And also I tried to do something with returning data from c++. In this way args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world").ToLocalChecked()); it works, but if I make like this:
string s = "world";
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, s).ToLocalChecked());
I get an error error C2664: "v8::MaybeLocal<v8::String> v8::String::NewFromUtf8(v8::Isolate *,const char *,v8::NewStringType,int)": cannot convert argument 2 from "std::string" to "const char *"
And I have no idea what is wrong here. Did someone has exprience working with c++ addons and v8 types, How to do that?
For understanding v8::String, the latest version of the docs help: https://v8docs.nodesource.com/node-14.1/d4/d1b/classv8_1_1_string_1_1_utf8_value.html (some signatures have changed a bit since the days of Node 0.8 -- learning how to make sense of the compiler's error messages is highly recommended if you want to develop with C++!).
For understanding std::string, see some C++ documentation, e.g.: https://en.cppreference.com/w/cpp/string/basic_string
If you need an actual example, you can look at V8's samples/process.cc, which has a function ObjectToString that converts any JS object (e.g. a v8::String) to a std::string. It's only two lines!

What is going on with 'gets(stdin)' on the site coderbyte?

Coderbyte is an online coding challenge site (I found it just 2 minutes ago).
The first C++ challenge you are greeted with has a C++ skeleton you need to modify:
#include <iostream>
#include <string>
using namespace std;
int FirstFactorial(int num) {
// Code goes here
return num;
}
int main() {
// Keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
If you are little familiar with C++ the first thing* that pops in your eyes is:
int FirstFactorial(int num);
cout << FirstFactorial(gets(stdin));
So, ok, the code calls gets which is deprecated since C++11 and removed since C++14 which is bad in itself.
But then I realize: gets is of type char*(char*). So it shouldn't accept a FILE* parameter and the result shouldn't be usable in the place of an int parameter, but ... not only it compiles without any warnings or errors, but it runs and actually passes the correct input value to FirstFactorial.
Outside of this particular site, the code doesn't compile (as expected), so what is going on here?
*Actually the first one is using namespace std but that is irrelevant to my issue here.
I'm the founder of Coderbyte and also the guy who created this gets(stdin) hack.
The comments on this post are correct that it is a form of find-and-replace, so let me explain why I did this really quickly.
Back in the day when I first created the site (around 2012), it only supported JavaScript. There was no way to "read in input" in JavaScript running in the browser, and so there would be a function foo(input) and I used the readline() function from Node.js to call it like foo(readline()). Except I was a kid and didn't know better, so I literally just replaced readline() with the input at run-time. So foo(readline()) became foo(2) or foo("hello") which worked fine for JavaScript.
Around 2013/2014 I added more languages and used third-party service to evaluate code online, but it was very difficult to do stdin/stdout with the services I was using, so I stuck with the same silly find-and-replace for languages like Python, Ruby, and eventually C++, C#, etc.
Fast forward to today, I run the code in my own containers, but never updated the way stdin/stdout works because people have gotten used to the weird hack (some people have even posted in forums explaining how to get around it).
I know it is not best practice and it isn't helpful for someone learning a new language to see hacks like this, but the idea was for new programmers to not worry about reading input at all and just focus on writing the algorithm to solve the problem. One common complaint about coding challenge sites years ago was that new programmers would spend a lot of time just figuring out how to read from stdin or read lines from a file, so I wanted new coders to avoid this problem on Coderbyte.
I'll be updating the entire editor page soon along with the default code and stdin reading for languages. Hopefully then C++ programmers will enjoy using Coderbyte more :)
I am intrigued. So, time to put the investigation goggles on and since I don't have access to the compiler or compilation flags I need to get inventive. Also because nothing about this code makes sense it's not a bad idea question every assumption.
First let's check the actual type of gets. I have a little trick for that:
template <class> struct Name;
int main() {
Name<decltype(gets)> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
And that looks ... normal:
/tmp/613814454/Main.cpp:16:19: warning: 'gets' is deprecated [-Wdeprecated-declarations]
Name<decltype(gets)> n;
^
/usr/include/stdio.h:638:37: note: 'gets' has been explicitly marked deprecated here
extern char *gets (char *__s) __wur __attribute_deprecated__;
^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:254:51: note: expanded from macro '__attribute_deprecated__'
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
^
/tmp/613814454/Main.cpp:16:26: error: implicit instantiation of undefined template 'Name<char *(char *)>'
Name<decltype(gets)> n;
^
/tmp/613814454/Main.cpp:12:25: note: template is declared here
template <class> struct Name;
^
1 warning and 1 error generated.
gets is marked as deprecated and has the signature char *(char *). But then how is FirstFactorial(gets(stdin)); compiling?
Let's try something else:
int main() {
Name<decltype(gets(stdin))> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Which gives us:
/tmp/286775780/Main.cpp:15:21: error: implicit instantiation of undefined template 'Name<int>'
Name<decltype(8)> n;
^
Finally we are getting something: decltype(8). So the entire gets(stdin) was textually replaced with the input (8).
And the things get weirder. The compiler error continues:
/tmp/596773533/Main.cpp:18:26: error: no matching function for call to 'gets'
cout << FirstFactorial(gets(stdin));
^~~~
/usr/include/stdio.h:638:14: note: candidate function not viable: no known conversion from 'struct _IO_FILE *' to 'char *' for 1st argument
extern char *gets (char *__s) __wur __attribute_deprecated__;
So now we get the expected error for cout << FirstFactorial(gets(stdin));
I checked for a macro and since #undef gets seems to do nothing it looks like it isn't a macro.
But
std::integral_constant<int, gets(stdin)> n;
It compiles.
But
std::integral_constant<int, gets(stdin)> n; // OK
std::integral_constant<int, gets(stdin)> n2; // ERROR wtf??
Doesn't with the expected error at the n2 line.
And again, almost any modification to main makes the line cout << FirstFactorial(gets(stdin)); spit out the expected error.
Moreover the stdin actually seems to be empty.
So I can only conclude and speculate they have a little program that parses the source and tries (poorly) to replace gets(stdin) with the test case input value before actually feeding it into the compiler. If anybody has a better theory or actually knows what they are doing please share!
This is obviously a very bad practice. While researching this I found there is at least a question here (example) about this and because people have no idea that there is a site out there who does this their answer is "don't use gets use ... instead" which is indeed a good advice but only confuses the OP more since any attempt at a valid read from stdin will fail on this site.
TLDR
gets(stdin) is invalid C++. It's a gimmick this particular site uses (for what reasons I cannot figure out). If you want to continue to submit on the site (I am neither endorsing it neither not endorsing it) you have to use this construct that otherwise would not make sense, but be aware that it is brittle. Almost any modifications to main will spit out an error. Outside of this site use normal input reading methods.
I tried the following addition to main in the Coderbyte editor:
std::cout << "gets(stdin)";
Where the mysterious and enigmatic snippet gets(stdin) appears inside a string literal. This shouldn't possibly be transformed by anything, not even the preprocessor, and any C++ programmer should expect this code to print the exact string gets(stdin) to the standard output. And yet we see the following output, when compiled and run on coderbyte:
8
Where the value 8 is taken straight from the convenient 'input' field under the editor.
From this, it's clear that this online editor is performing blind find-and-replace operations on the source code, substitution appearances of gets(stdin) with the user's 'input'. I would personally call this a misuse of the language that's worse than careless preprocessor macros.
In the context of an online coding challenge website, I'm worried by this because it teaches unconventional, non-standard, meaningless, and at least unsafe practices like gets(stdin), and in a manner that can't be repeated on other platforms.
I'm sure it can't be this hard to just use std::cin and just stream input to a program.

Wrong data type for free() in Fortran

I've been asked to use a library provided here and I was following the instructions to build it in Windows, those are located here.
Now I downloaded Intel Parallel Studio XE as requested and did everything as in the instructions but there's a problem inside the code that I can't figure out completely how to solve it. The compiler says Error #6362: The data type(s) of the argument(s) are invalid..
The lines that give trouble are both the same: call free(adr(n))
And the declaration of adr(n) is what I don't know if it is correct or not since I haven't touched FORTRAN 77 in a while. It is: adr(n) = malloc(length*ipa) where ipa and length are properly defined but I don't know if adr(n) is already defined somewhere else in the header files. Should I just add a declaration at the top (I heard FORTRAN needs declarations at the top) or should I do something else? What I know is that adr(n) should be length*ipa bytes but not if it should be a specific type or not, and I don't remember how to do something along the lines of char * adr = (char *) malloc(length*ipa); as I would do in C.
This was asked and answered at https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/801638 The source being used declared the variable as integer*8 (nonstandard), but a 32-bit build was being done. Since the Intel compiler treats malloc and free as intrinsics, it detected the mismatch.
In Fortran when you pass an array to a subroutine you do not include an index. By passing adr(n) you are only passing the nth element of adr to the subroutine. You most likely want to pass the whole array like this:
call free(adr)
If this does not do it, please post a Minimal, Complete, and Verifiable example.
Welcome to stackoverflow. I suggest you take the tour. and learn how to ask good questions.

movefile() fails error 2 or 123

I'm updating a c++ routine to move files that was written in visual studio express 2008/2010. I'm now running VS Express 2012
Obviously there are changes to the compiler because string functions have to be upgraded to strcpy_s etc. No problem. This is a console app. I never extended my C++ knowledge past C++ to C# etc. as I need little more than to be able to write small utils to do things on the command line. Still I'm able to write somewhat complex utilities.
My issue is movefile() function always fails to move with either error 2 or 123. I'm working in C:\users\alan\downloads folder so I know I have permission. I know the file is there. Small snippet of code is:
char source=".\\test.txt"; // edited for clarity.
char dest=".\\test.txt1";
printf("\nMove\n %s\n to %s\n",source,dest); // just to see what is going on
MoveFile((LPCWSTR) source, (LPCWSTR) dest);
printf("Error %u\n",GetLastError());
output is :
Move
.\test.txt
to .\test.txt1
Error 2
All of my strings are simple char strings and I'm not exactly sure, even after reading, what LPCWSTR was type def'd for and if this is the culprit. So to get this to compile I simply typedef'd my strings. And it compiles. But still it won't move the files.
The code is more complex in developing the source & dest variables but I've reduce it to a simple "just append a 1 to the file name" situation to see if I can just simply rename it. I thought C:\xxx\yyy\zzz\test.txt was maybe wrong in some fashion but that idea fell though with the above test. I've done it with and without the .\ same issue. I'm running out of ideas other than making my own fileopen read/write binary function to replace movefile(). I'm really against that but if I have to I will.
EDIT: I pasted the printf from original code that used FullPathName, I've corrected the snippet.
The fact that you are casting your arguments to LPCWSTR suggests that you are compiling your program with UNICODE defined, which means you are calling MoveFileW and the compiler warned about an argument type mismatch.
Inserting a cast does not fix that. You are telling the compiler to stop complaining, but you haven't actually fixed the problem (the underlying data is still wrong).
Actual solutions:
Use WCHAR as MoveFileW expects (or TCHAR/LPTSTR and the _T macro).
Explicitly call MoveFileA
Compile without UNICODE defined.
Thanks Andrew Medico. I used MoveFileA and the program seems to work now.
I'm not sure I turned off unicode, but I did change one item in the properties.
I'll need to read up on the compiler about unicode/ansi settings. But for now the issue is fixed and I'm sure I've got the idea of what I need to do. "research"!!!!

Why is this a memory copying error - Insure++ false positive?

I've been trying run Insure++ with some scientific code and it reports many errors, although to be fair it officially does not support K&R C and I don't know what having a lot of K&R functions has done to its evaluation process. The C and C++ code it is testing is being run in a DLL invoked from a WPF application.
One error report that puzzles me is the following, which I'm confident is safe code but am trying to work out why it thinks is an error (it does work). I'd be interested if anyone has an insight into why this might be an error condition.
[MacImagePlot.c:984] **READ_OVERFLOW**
SetCursorQD(*GetCursorQD(watchCursor));
Reading overflows memory: GetCursorQD(watchCursor)
bbbbb
| 4 | 4 |
rrrrr
Reading (r) : 0x5639d164 thru 0x5639d167 (4 bytes)
From block (b) : 0x5639d160 thru 0x5639d163 (4 bytes)
gWatchCursor, declared at WPFMacGraphics.cpp, 418
for some very simple code.
typedef int Cursor;
typedef Cursor* CursPtr;
typedef CursPtr* CursHandle;
CursHandle GetCursorQD (short cursorID);
void SetCursorQD (const Cursor *crsr);
enum {
....
watchCursor = 4
};
// file globals
Cursor gWatchCursor=watchCursor;
CursPtr gWatchCursorPtr = &gWatchCursor;
CursHandle GetCursorQD (short cursorID)
{
if (cursorID==watchCursor) // this is actually the only case ever called
return &gWatchCursorPtr;
return 0;
}
I'm not familiar at all with the tools you're talking about, but have you verified that your GetCursorQD function is returning the pointer you expect and not NULL/0?
Perhaps something wonky happened with your enum definition for watchCursor (such as it being declared differently elsewhere, or it picking up a local variable instead of the enum).
I hate to say it but I suspect your problem is going to be the lack of some arcane function modifiers needed to ensure that data on the stack isn't getting munged when crossing the DLL boundary. I'd suggest writing a simple app that replicates the code but does it all in one module and see if Insure++ still detects an error. If it doesn't, get ready to wade through __declspec documentation.
I assume that the following line is the Problem:
if (cursorID==watchCursor)
cursorID is defined as short (usually 2 Bytes)
watchCursor is part of a enum and thus of type int (4 Bytes on a 32Bit OS)
This actually is not a problem. The compiler will cast one of both parameters correctly, as far as the enum value will not exceed a 2 Byte range.
By my experience all static (as well as runtime-) code analysis tools report many false positives (i tried some of them). They of course help, but it takes quite a while to assert false positives from real bugs.
Like Soapbox, I am not familiar with Insure++.
But looking at the code, it is admittedly a bit confusing...so
That typedef makes CursHandle effectively a pointer to pointer to int...
CursHandle is a pointer of type CursPtr
CursPtr is a pointer of type Cursor
Cursor is typedef'd to type int
yet in the GetCursorQD, you are using a 'double address of' int? The reason I say 'double address' is the function is returning a address of gWatchCursorPtr (&gWatchCursorPtr) of type CursHandle, which in turn is a global variable which is a address of gWatchCursor (&gWatchCursor) which is of type Cursor.
Your definition of the return type for the function does not match up with the global variable name's typeof despite the typedef's...that's what my thinking is...
Hope this helps,
Best regards,
Tom.